package com.cloudkeeper.leasing.identity.controller.impl;

import cn.hutool.json.JSONObject;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.cloudkeeper.leasing.base.model.Result;
import com.cloudkeeper.leasing.identity.controller.VillageCadresController;
import com.cloudkeeper.leasing.identity.domain.*;
import com.cloudkeeper.leasing.identity.dto.InformationAudit.InformationAuditDTO;
import com.cloudkeeper.leasing.identity.dto.familyinfo.FamilyInfoDTO;
import com.cloudkeeper.leasing.identity.dto.familyworkinfo.FamilyWorkInfoDTO;
import com.cloudkeeper.leasing.identity.dto.honourinfo.HonourInfoDTO;
import com.cloudkeeper.leasing.identity.dto.promotioncadres.PromotionCadresSearchable;
import com.cloudkeeper.leasing.identity.dto.rewardinfo.RewardInfoDTO;
import com.cloudkeeper.leasing.identity.dto.traininginfo.TrainingInfoDTO;
import com.cloudkeeper.leasing.identity.dto.villagecadres.*;
import com.cloudkeeper.leasing.identity.dto.villagecadrestemporary.VillageCadresTemporarySearchable;
import com.cloudkeeper.leasing.identity.dto.villagecadresterm.VillageCadresTermDTO;
import com.cloudkeeper.leasing.identity.service.*;
import com.cloudkeeper.leasing.identity.vo.*;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Nonnull;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 村干部管理 controller
 * @author cqh
 */
@RestController
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class VillageCadresControllerImpl implements VillageCadresController {

    /** 村干部管理 service */
    private final VillageCadresService villageCadresService;
    /** 村干部管理 service */
    private final VillageCadresTermService villageCadresTermService;
    private final SysLogService sysLogService;

    private final CadrePositionService cadrePositionService;

    private final StatisticsService statisticsService;

    private final PromotionCadresService promotionCadresService;

    private final HonourInfoService honourInfoService;

    private final KPIVillageStatisticsService kpiVillageStatisticsService;

    /** 村干部临时表 service */
    private final VillageCadresTemporaryService villageCadresTemporaryService;

    private final SysDistrictService sysDistrictService;
    private final CadreTaskService cadreTaskService;
    private final InformationAuditService informationAuditService;
    /**
     * 职务对应薪酬等级
     */
    private final static Map<String,Integer> map = new HashMap<String,Integer>(){{
        put("IN_SECRETARY_DEPUTY_SECRETARY",4);//村党委副书记
        put("IN_SECRETARY_PARTY_COMMITTEE_MEMBER",2);//村党委委员
        put("IN_SECRETARY_GENERAL_PRATY_BRANCH_DEPUTY_SECRETARY",4);//村党总支副书记
        put("IN_SECRETARY_GENERAL_PRATY_BRANCH_MEMBER",2);//村党总支委员
        put("IN_SECRETARY_DIRECTOR",4);//村委会主任
        put("IN_SECRETARY_DEPUTY_DIRECTOR",3);//副主任
        put("IN_SECRETARY_TWO_COMMITTEE_MEMBER",2);//村委会委员
        put("IN_SECRETARY_DISCIPLINE_INSPECTION_COMMISSION_SECRETARY",1);//村纪委书记
        put("IN_SECRETARY_DISCIPLINE_INSPECTION_COMMISSION_MEMBER",1);//村纪委委员
        put("IN_SECRETARY_ACCOUNTING",3);//会计
        put("IN_SECRETARY_BATTALION_COMMANDER",2);//民兵营长
        put("IN_SECRETARY_WOMEN_PRESIDENT",2);//妇联主席
        put("IN_SECRETARY_LEAGUE_BRANCH_SECRETARY",1);//团支部书记
        put("OUT_SECRETARY",1);//乡村特聘岗

    }};
    /**
     * 薪酬等级
     */
    private final static Map<String,String> salaryMap = new HashMap<String,String>(){{
        put("1","一档（省标50%）");
        put("2","二档（省标70%）");
        put("3","三档（省标90%）");
        put("4","四档（省标95%）");
    }};
    @Override
    public Result<VillageCadresVO> findOne(@ApiParam(value = "村干部管理id", required = true) @PathVariable String id) {
        Optional<VillageCadres> villageCadresOptional = villageCadresService.findOptionalById(id);
        return villageCadresOptional.map(villageCadres -> Result.of(villageCadres.convert(VillageCadresVO.class))).orElseGet(Result::ofNotFound);
    }

    @Override
    @Transactional
    public Result<VillageCadresVO> departure(@ApiParam(value = "村干部管理id", required = true)@RequestBody VillageCadresTermDTO villageCadresTermDTO) {
        // 岗位关系端移除
        String positionId = villageCadresTermDTO.getPositionId();
        Optional<CadrePosition> optionalById = cadrePositionService.findOptionalById(positionId);
        if (StringUtils.isEmpty(positionId) || !optionalById.isPresent()) {
            return Result.of(404, "该职位不存在");
        }
        CadrePosition currentPosition = optionalById.get();
        currentPosition.setCadreId(null);
        cadrePositionService.saveAndFlush(currentPosition);

        // 人员退休标记
        Optional<VillageCadres> optional = villageCadresService.findOptionalById(villageCadresTermDTO.getCadresId());
        if (!optional.isPresent()) {
            return Result.of(404, "该村干部不存在");
        }
        // 没有任何职位的时候标记退休
        VillageCadres villageCadres = optional.get();
//        List<CadrePosition> cadrePosition = villageCadres.getCadrePosition();
//        if (cadrePosition.size() == 0) {
//
//        }
        villageCadres.setHasRetire("1");
        villageCadresService.save(villageCadres);

        // 任期信息记录
        VillageCadresTerm villageCadresTerm = villageCadresTermService.findByCadresIdAndTermType(villageCadres.getId(), "0");
        if (villageCadresTerm != null){
            villageCadresTerm.setDepartureTime(LocalDate.now());
            villageCadresTerm.setTermFile(villageCadresTermDTO.getTermFile());
            villageCadresTermService.save(villageCadresTerm);
            VillageCadresTermDTO vDto= new VillageCadresTermDTO();
            BeanUtils.copyProperties(villageCadresTerm, vDto, "id");
            VillageCadresTerm convert = vDto.convert(VillageCadresTerm.class);
            convert.setTermType("1");
            villageCadresTermService.save(convert);
        }
        String msg = villageCadresService.actionLog("移除","[村干部信息]", villageCadres.getName());
        sysLogService.pushLog(this.getClass().getName(),msg,villageCadresService.getTableName(),villageCadres.getId());
        return Result.ofUpdateSuccess(villageCadres.convert(VillageCadresVO.class));
    }

    @Override
    public Result<VillageCadresVO> cadresDeparture(@RequestBody VillageCadresTermDTO villageCadresTermDTO) {
        // 人员退休标记
        Optional<VillageCadres> optional = villageCadresService.findOptionalById(villageCadresTermDTO.getCadresId());
        if (!optional.isPresent()) {
            return Result.of(404, "该村干部不存在");
        }
        // 没有任何职位的时候标记退休
        VillageCadres villageCadres = optional.get();
        villageCadres.setHasRetire("1");
        villageCadresService.save(villageCadres);
        return Result.ofUpdateSuccess(villageCadres.convert(VillageCadresVO.class));
    }

    @Override
    public Result<List<CadresExamineVO>> getExamines(String cadresType, String districtId) {
        return Result.of(villageCadresService.getExamines(cadresType, districtId));
    }

    @Override
    public Result<VillageCadresVO> add(@ApiParam(value = "村干部管理 DTO", required = true) @RequestBody @Validated VillageCadresDTO villageCadresDTO) {
        VillageCadres villageCadres = villageCadresService.save(villageCadresDTO.convert(VillageCadres.class));
        String msg;
        if (villageCadres == null) {
            msg = villageCadresService.actionLog("新增村干部失败，职位不存在","[村干部信息]", villageCadres.getName());
            sysLogService.pushLog(this.getClass().getName(),msg,villageCadresService.getTableName(),villageCadres.getId());
            return Result.ofNotFound();
        }

        //添加村干部任期信息----开始
        VillageCadresTerm villageCadresTerm = new VillageCadresTerm();
        villageCadresTerm.setCadresId(villageCadres.getId());
        villageCadresTerm.setCadresName(villageCadres.getName());
        villageCadresTerm.setAppointmentTime(LocalDate.now());
        villageCadresTerm.setDistrictId(villageCadres.getDistrictId());
        villageCadresTerm.setDistrictName(villageCadres.getDistrictName());
        villageCadresTerm.setCadresType(villageCadres.getCadresType());
        villageCadresTerm.setTermType("0");
        villageCadresTermService.save(villageCadresTerm);
        //添加村干部任期信息----结束

        msg = villageCadresService.actionLog("新增","[村干部信息]", villageCadres.getName());
        sysLogService.pushLog(this.getClass().getName(),msg,villageCadresService.getTableName(),villageCadres.getId());
        return Result.ofAddSuccess(villageCadres.convert(VillageCadresVO.class));
    }

    @Override
    public Result<VillageCadresVO> addBaseInfo(@RequestBody @Validated VillageCadresDTO villageCadresDTO) {
        VillageCadres villageCadres = villageCadresService.saveBaseInfo(villageCadresDTO);

        String msg = villageCadresService.actionLog("新增","[村干部信息]", villageCadres.getName());
        sysLogService.pushLog(this.getClass().getName(),msg,villageCadresService.getTableName(),villageCadres.getId());

        return Result.ofAddSuccess(villageCadres.convert(VillageCadresVO.class));
    }

    @Override
    public Result<VillageCadresVO> update(@ApiParam(value = "村干部管理id", required = true) @PathVariable String id,
        @ApiParam(value = "村干部管理 DTO", required = true) @RequestBody @Validated VillageCadresDTO villageCadresDTO) {
        Optional<VillageCadres> villageCadresOptional = villageCadresService.findOptionalById(id);
        if (!villageCadresOptional.isPresent()) {
            return Result.ofLost();
        }
        VillageCadres villageCadres = villageCadresService.save(villageCadresDTO);
        if (villageCadres == null) {
            return Result.of(500, "当前无任务或者干部类型未明确");
        }
        String  msg= villageCadresService.actionLog("修改","[村干部信息]", villageCadres.getName());
        sysLogService.pushLog(this.getClass().getName(),msg,villageCadresService.getTableName(),villageCadres.getId());
        return Result.ofUpdateSuccess(villageCadres.convert(VillageCadresVO.class));
    }

    @Override
    public Result<VillageCadresTemporaryVO> updateTemporary(@ApiParam(value = "村干部管理id", required = true) @PathVariable String id,
                                                            @ApiParam(value = "村干部管理 DTO", required = true) @RequestBody @Validated VillageCadresDTO villageCadresDTO) {
        Optional<VillageCadres> villageCadresOptional = villageCadresService.findOptionalById(id);
        if (!villageCadresOptional.isPresent()) {
            return Result.ofLost();
        }
        VillageCadresTemporarySearchable temporarySearchable = new VillageCadresTemporarySearchable();
        temporarySearchable.setCadresId(id);
        temporarySearchable.setStatue("0");
        List<VillageCadresTemporary> l = villageCadresTemporaryService.findAll(temporarySearchable);
        if (!CollectionUtils.isEmpty(l)){
            villageCadresTemporaryService.delete(l.get(0));
        }
        SysDistrict byDistrictId = sysDistrictService.findByDistrictId(villageCadresDTO.getDistrictId());
        villageCadresDTO.setParentDistrictId(byDistrictId.getOrgParent());
        villageCadresDTO.setParentDistrictName(byDistrictId.getParentName());
        villageCadresDTO.setDistrictName(byDistrictId.getDistrictName());
        villageCadresDTO.setState("0");
        VillageCadresVO convert = villageCadresDTO.convert(VillageCadresVO.class);

        List<HonourInfoDTO> honours = villageCadresDTO.getHonours();
        List<RewardInfoDTO> rewards = villageCadresDTO.getRewards();
        List<FamilyInfoDTO> familyInfos = villageCadresDTO.getFamilyInfoDTOS();
        List<FamilyWorkInfoDTO> familyWorkInfos = villageCadresDTO.getFamilyWorkInfoDTOS();
        List<TrainingInfoDTO> trainingInfoDTOS = villageCadresDTO.getTrainingInfoDTOS();
        convert.setHonours(HonourInfoDTO.convert(honours,HonourInfoVO.class));
        convert.setRewards(RewardInfoDTO.convert(rewards,RewardInfoVO.class));
        convert.setFamilyWorkInfoVOS(FamilyWorkInfoDTO.convert(familyWorkInfos,FamilyWorkInfoVO.class));
        convert.setFamilyInfoVOS(FamilyInfoDTO.convert(familyInfos,FamilyInfoVO.class));
        convert.setTrainingInfoVOS(TrainingInfoDTO.convert(trainingInfoDTOS,TrainingInfoVO.class));
        String json = JSONArray.toJSONString(convert, SerializerFeature.WriteMapNullValue,SerializerFeature.WriteNullListAsEmpty);
        VillageCadresTemporary v = new VillageCadresTemporary();
        v.setCadresId(id);
        v.setCadresInfo(json);
        v.setStatue("0");
        VillageCadresTemporary villageCadresTemporary = villageCadresTemporaryService.saveAndFlush(v);
        return Result.ofUpdateSuccess(villageCadresTemporary.convert(VillageCadresTemporaryVO.class));
    }

    /**
     * 更新提交，绕开乐观锁
     *
     * @param id
     * @param villageCadresDTO
     * @return
     */
    @Override
    public Result<VillageCadresTemporaryVO> secretarySubmitTemporary(@ApiParam(value = "村干部管理id", required = true) @PathVariable String id,
                                                                     @ApiParam(value = "村干部管理 DTO", required = true) @RequestBody @Validated VillageCadresDTO villageCadresDTO) {
        Optional<VillageCadres> villageCadresOptional = villageCadresService.findOptionalById(id);
        if (!villageCadresOptional.isPresent()) {
            return Result.ofLost();
        }
        VillageCadresTemporarySearchable temporarySearchable = new VillageCadresTemporarySearchable();
        temporarySearchable.setCadresId(id);
        temporarySearchable.setStatue("0");
        List<VillageCadresTemporary> l = villageCadresTemporaryService.findAll(temporarySearchable);
        if (!CollectionUtils.isEmpty(l)){
            villageCadresTemporaryService.delete(l.get(0));
        }
        SysDistrict byDistrictId = sysDistrictService.findByDistrictId(villageCadresDTO.getDistrictId());
        villageCadresDTO.setParentDistrictId(byDistrictId.getOrgParent());
        villageCadresDTO.setParentDistrictName(byDistrictId.getParentName());
        villageCadresDTO.setDistrictName(byDistrictId.getDistrictName());
        villageCadresDTO.setState("0");
        VillageCadresVO convert = villageCadresDTO.convert(VillageCadresVO.class);

        List<HonourInfoDTO> honours = villageCadresDTO.getHonours();
        List<RewardInfoDTO> rewards = villageCadresDTO.getRewards();
        List<FamilyInfoDTO> familyInfos = villageCadresDTO.getFamilyInfoDTOS();
        List<FamilyWorkInfoDTO> familyWorkInfos = villageCadresDTO.getFamilyWorkInfoDTOS();
        List<TrainingInfoDTO> trainingInfoDTOS = villageCadresDTO.getTrainingInfoDTOS();
        convert.setHonours(HonourInfoDTO.convert(honours,HonourInfoVO.class));
        convert.setRewards(RewardInfoDTO.convert(rewards,RewardInfoVO.class));
        convert.setFamilyWorkInfoVOS(FamilyWorkInfoDTO.convert(familyWorkInfos,FamilyWorkInfoVO.class));
        convert.setFamilyInfoVOS(FamilyInfoDTO.convert(familyInfos,FamilyInfoVO.class));
        convert.setTrainingInfoVOS(TrainingInfoDTO.convert(trainingInfoDTOS,TrainingInfoVO.class));
        String json = JSONArray.toJSONString(convert, SerializerFeature.WriteMapNullValue,SerializerFeature.WriteNullListAsEmpty);
        VillageCadresTemporary v = new VillageCadresTemporary();
        v.setCadresId(id);
        v.setCadresInfo(json);
        v.setStatue("1");
        VillageCadresTemporary villageCadresTemporary = villageCadresTemporaryService.saveAndFlush(v);
        CadreTask currentBaseInfoTask = cadreTaskService.getSecretaryTask();
        InformationAudit informationAudit = new InformationAudit();
        informationAudit.setVillageId(villageCadresDTO.getId());
        informationAudit.setTaskId(currentBaseInfoTask.getId());
        informationAudit.setProcessType(currentBaseInfoTask.getType());
        informationAudit.setStatus("1");
        informationAudit.setAuditor(villageCadresDTO.getParentDistrictName());
        informationAudit.setAuditAdvice("提交了该村干部信息！");
        informationAuditService.save(informationAudit);
        return Result.ofUpdateSuccess(villageCadresTemporary.convert(VillageCadresTemporaryVO.class));
    }

    @Override
    public Result delete(@ApiParam(value = "村干部管理id", required = true) @PathVariable String id) {
        VillageCadres villageCadres = villageCadresService.findById(id);
        villageCadresService.deleteById(id);
        String  msg= villageCadresService.actionLog("删除","[村干部信息]", villageCadres.getName());
        sysLogService.pushLog(this.getClass().getName(),msg,villageCadresService.getTableName(),villageCadres.getId());
        return Result.ofDeleteSuccess();
    }

    @Override
    public Result<List<VillageCadresVO>> list(@ApiParam(value = "村干部管理查询条件", required = true) @RequestBody VillageCadresSearchable villageCadresSearchable,
        @ApiParam(value = "排序条件", required = true) Sort sort) {
        List<VillageCadres> villageCadresList = villageCadresService.findAll(villageCadresSearchable, sort);
        List<VillageCadresVO> villageCadresVOList = VillageCadres.convert(villageCadresList, VillageCadresVO.class);
        return Result.of(villageCadresVOList);
    }

    @Override
    public Result<Page<VillageCadresVO>> page(@ApiParam(value = "村干部管理查询条件", required = true) @RequestBody VillageCadresSearchable villageCadresSearchable,
        @ApiParam(value = "分页参数", required = true) Pageable pageable) {
        DetachedCriteria detachedCriteria = setParam(villageCadresSearchable);
        Integer total = villageCadresService.getTotalCount(detachedCriteria);
        pageable.getSort().forEach(item -> {
            if (item.isAscending()) {
                detachedCriteria.addOrder(Order.asc(item.getProperty()));
            } else {
                detachedCriteria.addOrder(Order.desc(item.getProperty()));
            }
        });
        Page<VillageCadres> villageCadresPage = villageCadresService.findAll(detachedCriteria, pageable, total);
        Page<VillageCadresVO> villageCadresVOPage = VillageCadres.pageConvert(villageCadresPage, VillageCadresVO.class);
        return Result.of(villageCadresVOPage);
    }

    @Override
    public Result<Long> countALl(@RequestBody VillageCadresSearchable villageCadresSearchable) {
        Long aLong = villageCadresService.countAllByDistrictId(villageCadresSearchable.getDistrictId());
        return Result.of(aLong);
    }

    @Override
    public Result<Boolean> submit( @PathVariable String id) {
        Optional<VillageCadres> optionalById = villageCadresService.findOptionalById(id);

        if(optionalById.isPresent()){
            return  Result.of(villageCadresService.submit(optionalById.get()));
        }
        return Result.ofNotFound();
    }

    @Override
    public Result<Boolean> verify(@PathVariable("id") String id, @PathVariable("code") String code, @RequestBody InformationAuditDTO informationAuditDTO2) {
        return Result.of(villageCadresService.virify(id,code,informationAuditDTO2));
    }

    @Override
    public Result<String> initPost() {
        try {
            villageCadresService.initPost();
        } catch (Exception e) {
            System.out.println(e);
            return Result.of("false");
        }

        return Result.of("true");
    }

    @Override
    public Result<SecretaryNumberVO> countNumber() {
        SecretaryNumberVO secretaryNumberVO = villageCadresService.countNumber();
        return Result.of(secretaryNumberVO);
    }

    @Override
    public Result<SecretaryNumberVO> countNumber(HttpServletRequest request, HttpServletResponse response, @RequestBody VillageCadresSearchable villageCadresSearchable) {
        DetachedCriteria detachedCriteria = setParam(villageCadresSearchable);
        List<VillageCadres> list = villageCadresService.findAll(detachedCriteria);
        List<VillageCadresVO> villageCadresVOS = VillageCadres.pageConvert(list, VillageCadresVO.class);
        return null;
    }

    @Override
    public Result<Boolean> init() {
        villageCadresService.initCadres();
        return Result.of(true);
    }

    @Override
    public Result<Boolean> secretarySubmit(@PathVariable String id) {
        Optional<VillageCadres> optionalById = villageCadresService.findOptionalById(id);

        if(optionalById.isPresent()){
            return  Result.of(villageCadresService.secretarySubmit(optionalById.get()));
        }
        return Result.ofNotFound();
    }

    @Override
    public Result<Boolean> secretaryReview(@PathVariable String id, @PathVariable String code, @RequestBody InformationAuditDTO informationAuditDTO2) {
        return Result.of(villageCadresService.secretaryReview(id,code,informationAuditDTO2));
    }

    /**
     * 校验村干部薪酬等级和职务是否匹配
     *
     * @return 审核
     */
    @Override
    public Result<Object> checkSalaryHasMatchingPost(@RequestBody CheckSalaryHasMatchingPostDTO checkSalaryHasMatchingPostDTO) {
        Map<String,Boolean> resMap = new HashMap<String,Boolean>(16);
        if (checkSalaryHasMatchingPostDTO != null && checkSalaryHasMatchingPostDTO.getPost() != null && checkSalaryHasMatchingPostDTO.getSalary() != null){
            String[] arr = checkSalaryHasMatchingPostDTO.getPost().split(",");
            List list = new ArrayList<Integer>();
            if (arr.length > 0){
                for (String s : arr){
                    if (map.containsKey(s)){
                        list.add(map.get(s));
                    }
                }
            }
            Integer max = (Integer)Collections.max(list);
            if (salaryMap.get(max.toString()).equals(checkSalaryHasMatchingPostDTO.getSalary())){
                resMap.put("res",true);
                return Result.of(resMap);
            }
        }
        resMap.put("res",false);
        return Result.of(resMap);
    }

    @Override
    public Result<Object> test() {
        ArrayList<String> objects = new ArrayList<>();
        objects.add("2001");
        objects.add("2002");
        objects.add("2003");
        objects.add("2005");
        objects.add("2006");
        objects.add("2008");
        objects.add("2010");
        objects.add("2011");
        objects.add("2012");
        objects.add("2014");
        int i = villageCadresService.calTopAmount(objects);
        return null;
    }

    @Override
    public Result<Boolean> updateManual() {
        return Result.of(villageCadresService.updateLevelManual());
    }

    @Override
    public Result<List<String>> findVillageWithoutCadres() {
        return Result.of(villageCadresService.findVillageWithoutCadres());
    }

    /**
     * 获取某年第一天日期
     * @param year 年份
     * @return Date
     */
    private Date getCurrYearFirst(int year){
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(Calendar.YEAR, year);
        Date currYearFirst = calendar.getTime();
        return currYearFirst;
    }

    /**
     * 获取某年最后一天日期
     * @param year 年份
     * @param year 年份
     * @return Date
     */
    private Date getCurrYearLast(int year){
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(Calendar.YEAR, year);
        calendar.roll(Calendar.DAY_OF_YEAR, -1);
        Date currYearLast = calendar.getTime();

        return currYearLast;
    }
    private DetachedCriteria setParam(VillageCadresSearchable villageCadresSearchable){
        DetachedCriteria detachedCriteria = DetachedCriteria.forClass(VillageCadres.class);
        Calendar date = Calendar.getInstance();
        int year = date.get(Calendar.YEAR);
        if (!StringUtils.isEmpty(villageCadresSearchable.getPost())) {
            detachedCriteria.createAlias("cadrePosition","a");
            detachedCriteria.add(Restrictions.eq("a.post", villageCadresSearchable.getPost()));
        }
        if(!StringUtils.isEmpty(villageCadresSearchable.getName())){
            //通过姓名模糊查询
            detachedCriteria.add(Restrictions.ilike("name", villageCadresSearchable.getName(), MatchMode.ANYWHERE));
        }
        if(!StringUtils.isEmpty(villageCadresSearchable.getCadresType())){
            //通过姓名模糊查询
            detachedCriteria.add(Restrictions.like("cadresType", villageCadresSearchable.getCadresType(),MatchMode.START));
        }
        if(!StringUtils.isEmpty(villageCadresSearchable.getDistrictId())){
            //通过组织模糊查询
            detachedCriteria.add(Restrictions.ilike("districtId", villageCadresSearchable.getDistrictId(), MatchMode.START));
        }
        if(!StringUtils.isEmpty(villageCadresSearchable.getQuasiAssessmentRank())){
            //通过员额村书记等级
            detachedCriteria.add(Restrictions.ilike("quasiAssessmentRank", villageCadresSearchable.getQuasiAssessmentRank(), MatchMode.ANYWHERE));
        }
        if(!StringUtils.isEmpty(villageCadresSearchable.getEducation())){
            //通过学历
            detachedCriteria.add(Restrictions.eq("education",villageCadresSearchable.getEducation()));
        }
        if(!StringUtils.isEmpty(villageCadresSearchable.getFullTimeEdu())){
            //通过全日制学历
            detachedCriteria.add(Restrictions.eq("fullTimeEdu",villageCadresSearchable.getFullTimeEdu()));
        }
        if(!StringUtils.isEmpty(villageCadresSearchable.getSex())){
            //通过性别
            detachedCriteria.add(Restrictions.eq("sex",villageCadresSearchable.getSex()));
        }
        if(!StringUtils.isEmpty(villageCadresSearchable.getPersonnelType())){
            //通过人员类型
            detachedCriteria.add(Restrictions.eq("personnelType",villageCadresSearchable.getPersonnelType()));
        }
        if(!StringUtils.isEmpty(villageCadresSearchable.getHasRetire())){
            //通过是否离退休
            detachedCriteria.add(Restrictions.eq("hasRetire",villageCadresSearchable.getHasRetire()));
        }
        if(!StringUtils.isEmpty(villageCadresSearchable.getAge())){
            //通过年龄
            String sql = "";
            if (villageCadresSearchable.getAge().equals("-1")){
                sql = "DATEDIFF(YEAR,birth,GETDATE()) > 50";
            }else if (villageCadresSearchable.getAge().equals("35")){
                sql = "DATEDIFF(YEAR,birth,GETDATE()) <= 35";
            }else {
                if("SECRETARY".equals(villageCadresSearchable.getCadresType())){
                    sql = "DATEDIFF(YEAR,birth,GETDATE()) <= "+villageCadresSearchable.getAge() +"and DATEDIFF(YEAR,birth,GETDATE()) >"+(Integer.valueOf(villageCadresSearchable.getAge())-5);
                }else {
                    sql = "DATEDIFF(YEAR,birth,GETDATE()) <= "+villageCadresSearchable.getAge() +"and DATEDIFF(YEAR,birth,GETDATE()) >"+(Integer.valueOf(villageCadresSearchable.getAge())-15);
                }
            }
            detachedCriteria.add(Restrictions.sqlRestriction(sql));
        }
        if (!StringUtils.isEmpty(villageCadresSearchable.getOnDutyTime())){
            //任职年限
            String sql = "";
            if (villageCadresSearchable.getOnDutyTime().equals("-1")){
                sql = "cast(onDutyTime as FLOAT) >= 20";
            }else if (villageCadresSearchable.getOnDutyTime().equals("1")){
                sql = "cast(onDutyTime as FLOAT) < 1";
            }else if (villageCadresSearchable.getOnDutyTime().equals("5")){
                sql = "cast(onDutyTime as FLOAT) < 5 and cast(onDutyTime as FLOAT) >= 1";
            }else {
                sql = "cast(onDutyTime as FLOAT) < "+villageCadresSearchable.getOnDutyTime() +"and cast(onDutyTime as FLOAT)  >="+(Integer.valueOf(villageCadresSearchable.getOnDutyTime())-5);
            }
            detachedCriteria.add(Restrictions.sqlRestriction(sql));
        }
        if (!StringUtils.isEmpty(villageCadresSearchable.getRank())){
            //职级等次
            detachedCriteria.add(Restrictions.eq("rank",villageCadresSearchable.getRank()));
        }
        if(!StringUtils.isEmpty(villageCadresSearchable.getEnterPartyTime())){
            //通过党龄
            String sql = "";
            if (villageCadresSearchable.getEnterPartyTime().equals("-1")){
                sql = "DATEDIFF(YEAR,partyTime,GETDATE()) >= 50";
            }else if (villageCadresSearchable.getEnterPartyTime().equals("1")){
                sql = "DATEDIFF(YEAR,partyTime,GETDATE()) < 1";
            }else if (villageCadresSearchable.getEnterPartyTime().equals("5")){
                sql = "DATEDIFF(YEAR,partyTime,GETDATE()) < 5 and DATEDIFF(YEAR,partyTime,GETDATE()) >= 1";
            }else if(Integer.valueOf(villageCadresSearchable.getEnterPartyTime())<=20){
                sql = "DATEDIFF(YEAR,partyTime,GETDATE()) < "+villageCadresSearchable.getEnterPartyTime() +"and DATEDIFF(YEAR,partyTime,GETDATE())  >="+(Integer.valueOf(villageCadresSearchable.getEnterPartyTime())-5);
            }else {
                sql = "DATEDIFF(YEAR,partyTime,GETDATE()) < "+villageCadresSearchable.getEnterPartyTime() +"and DATEDIFF(YEAR,partyTime,GETDATE())  >="+(Integer.valueOf(villageCadresSearchable.getEnterPartyTime())-10);
            }
            detachedCriteria.add(Restrictions.sqlRestriction(sql));
        }
        return detachedCriteria;
    }


    @GetMapping("/getCadresGroupByLevel")
    Result<List<CadresGroupByLevelVO>> getCadresGroupByLevel(String districtId) {
        return Result.of(villageCadresService.getCadresGroupByLevel(districtId));
    }

    @GetMapping("/downloadPromotion")
    @Transactional
    Result<String> downloadPromotion(String districtId, String taskId) {
        PromotionCadresSearchable promotionCadresSearchable = new PromotionCadresSearchable();
        if (districtId != null) {
            promotionCadresSearchable.setTownId(districtId);
        }
        promotionCadresSearchable.setTaskId(taskId);
        List<PromotionCadres> all = promotionCadresService.findAll(promotionCadresSearchable);
        if (all.size() == 0) {
            return Result.ofNotFound();
        }
        List<String> ids = all.stream().map(promotionCadres -> "'" + promotionCadres + "'").collect(Collectors.toList());
        String join = org.apache.commons.lang3.StringUtils.join(ids.toArray(), ",");
        String sql = "select * from village_cadres  WHERE id in ("+ join +")";
        return Result.of("下載成功", statisticsService.generateFileUrl(buildExportDTO(), sql));
    }

    private ExportDTO buildExportDTO() {
        ExportDTO exportDTO = new ExportDTO();
        List<VillageCadresStatisticsSearchable> list = new ArrayList<>();
        list.add(new VillageCadresStatisticsSearchable("parentDistrictName", "镇名"));
        list.add(new VillageCadresStatisticsSearchable("districtName", "村名"));
        list.add(new VillageCadresStatisticsSearchable("type", "类型"));
        list.add(new VillageCadresStatisticsSearchable("name", "姓名"));
        list.add(new VillageCadresStatisticsSearchable("sex", "性别"));
        list.add(new VillageCadresStatisticsSearchable("identityCard", "身份证"));
        list.add(new VillageCadresStatisticsSearchable("birth", "出生日期"));
        list.add(new VillageCadresStatisticsSearchable("nation", "民族"));
        list.add(new VillageCadresStatisticsSearchable("nativePlace", "籍贯"));
        list.add(new VillageCadresStatisticsSearchable("education", "学历"));
        list.add(new VillageCadresStatisticsSearchable("contact", "联系方式"));
        list.add(new VillageCadresStatisticsSearchable("partyTime", "入党时间"));
        list.add(new VillageCadresStatisticsSearchable("workTime", "工作时间"));
        list.add(new VillageCadresStatisticsSearchable("postExperience", "任职经历"));
        exportDTO.setExportFields(list);
        return exportDTO;
    }

    // 获得村书记疗养建议名单
    @GetMapping("/getRestSuggestSecretary")
    public Result<List<VillageCadresVO>> getRestSuggestSecretary() {
        DetachedCriteria detachedCriteria = DetachedCriteria.forClass(VillageCadres.class);
        detachedCriteria.add(Restrictions.in("quasiAssessmentRank",
                new ArrayList(){{
                    add("三级专职村书记");
                    add("四级专职村书记");
                    add("五级专职村书记");
                }}
        ));
        detachedCriteria.addOrder(Order.asc("districtId"));
        List<VillageCadres> all = villageCadresService.findAll(detachedCriteria);
        return Result.of(VillageCadres.convert(all, VillageCadresVO.class));
    }

    @GetMapping("/getLevelRelateInfo")
    public Result<VillageCadresLevelInfoVO> getLevelRelateInfo(@Nonnull String cadresId) {
        Optional<VillageCadres> optionalById = villageCadresService.findOptionalById(cadresId);
        if (!optionalById.isPresent()) {
            return Result.ofNotFound();
        }
        VillageCadres villageCadres = optionalById.get();
        VillageCadresLevelInfoVO villageCadresLevelInfoVO = new VillageCadresLevelInfoVO();
        BeanUtils.copyProperties(villageCadres, villageCadresLevelInfoVO);
        List<HonourInfo> honours = honourInfoService.findAllByCadresIdAndRewardsType(villageCadres.getId(), "表彰");
        villageCadresLevelInfoVO.setHonours(HonourInfo.convert(honours, HonourInfoVO.class));

        List<KPIVillageStatistics> allByCadresIdAndQuotaLevel = kpiVillageStatisticsService.findAllByCadresIdAndQuotaLevel(villageCadres.getId(), "0");
        villageCadresLevelInfoVO.setKpiVillageStatisticsVOS(KPIVillageStatistics.convert(allByCadresIdAndQuotaLevel, KPIVillageStatisticsVO.class));

        return Result.of(villageCadresLevelInfoVO);
    }

//    @GetMapping("/goBack/{cadresId}")
//    public Result<VillageCadresLevelInfoVO> goBack(@PathVariable String cadresId) {
//        Optional<VillageCadres> optionalById = villageCadresService.findOptionalById(cadresId);
//        if (!optionalById.isPresent()) {
//            return Result.ofNotFound();
//        }
//        VillageCadres villageCadres = optionalById.get();
//        villageCadres.setState("0");
//        return Result.of(villageCadresLevelInfoVO);
//    }
}
